#include "createmask.h"

/**
 * createMask by landmarks
 * @param 
 * @return
 */
void createMask(Mat mask1, Mat mask2, int* landmarkArray, int width, int height){
	vector <Point> landmarks;

	for (int i=0; i<FACEPP_POINT_COUNT; i++) {
		landmarks.push_back(Point(landmarkArray[2*i],landmarkArray[2*i + 1]));
	}

	// calculate the width of the face
	double face_width = sqrtf((landmarks[2].x - landmarks[11].x)*(landmarks[2].x - landmarks[11].x) + (landmarks[2].y - landmarks[11].y)*(landmarks[2].y - landmarks[11].y));
	// calculate the height of the face
	double face_height = 5.0/4.0 * sqrtf((landmarks[0].x - landmarks[35].x)*(landmarks[0].x - landmarks[35].x) + (landmarks[0].y - landmarks[35].y)*(landmarks[0].y - landmarks[35].y));

	int fixX = (int)(face_width/150);
	int fixY = (int)(face_height/150);

	// some tricks for enhancement?
	landmarks[41].x-=fixX;
	landmarks[41].y+=fixY;
	landmarks[44].x+=fixX;
	landmarks[44].y+=fixY;

	landmarks[62].x-=fixX;
	landmarks[62].y+=fixY;
	landmarks[63].x+=fixX;
	landmarks[63].y+=fixY;

	landmarks[57].y+=fixY;
	landmarks[61].y+=fixY;

	landmarks[55].y-=fixY * 2;
	landmarks[59].y-=fixY * 2;

	landmarks[62].x-=fixX * 3 / 2;
	landmarks[63].x+=fixX * 3 / 2;

	landmarks[37].x-=fixX * 3 / 2;
	landmarks[46].x+=fixX * 3 / 2;


	// Draw masks
	Mat mask(cvSize(width, height),CV_8UC1);
	mask=Mat::zeros(cvSize(width, height),0);

	// outline
	Point face_outline[7][26];
	Point Top,Tleft,Tright;
	int hMargin=(abs(landmarks[31].y-landmarks[27].y)+abs(landmarks[72].y-landmarks[77].y))/2;
	Top.x=(landmarks[33].x+landmarks[75].x)/2;
	Top.y=(landmarks[33].y+landmarks[75].y)/2-3*hMargin;
	Tleft.x=landmarks[35].x;
	Tleft.y=landmarks[35].y-1*hMargin;
	Tright.x=landmarks[81].x;
	Tright.y=landmarks[81].y-2*hMargin;

	face_outline[0][0]=landmarks[34];
	face_outline[0][1]=landmarks[29];
	for(int i=0;i<9;i++)
		face_outline[0][2+i]=landmarks[i+1];
	face_outline[0][11]=landmarks[0];
	for(int i=0;i<9;i++)
		face_outline[0][12+i]=landmarks[18-i];
	face_outline[0][21]=landmarks[79];
	face_outline[0][22]=landmarks[82];
	face_outline[0][23]=Point(Tright.x,Tright.y);
	face_outline[0][24]=Point(Top.x,Top.y);
	face_outline[0][25]=Point(Tleft.x,Tleft.y);

	const Point* ppt[1] = { face_outline[0] };
	int npt[] = { 26 };
	fillPoly( mask,ppt,npt,1,Scalar( 255, 255, 255 ), 8);

	cvtColor(mask, mask2, CV_GRAY2BGRA);

	// left eye
	// expand the left eye
	int left_eye_expand = (int)sqrtf((landmarks[25].x - landmarks[55].x)*(landmarks[25].x - landmarks[55].x) + (landmarks[25].y - landmarks[55].y)*(landmarks[25].y - landmarks[55].y))/3;
	
	landmarks[21].x -= left_eye_expand * 2;
	landmarks[25].x += left_eye_expand * 2;

	landmarks[26].y -= left_eye_expand;
	landmarks[27].y -= left_eye_expand;
	landmarks[28].y -= left_eye_expand;

	landmarks[19].y += left_eye_expand;
	landmarks[22].y += left_eye_expand;
	landmarks[23].y += left_eye_expand;

	face_outline[1][0]=landmarks[27];
	face_outline[1][1]=landmarks[26];
	face_outline[1][2]=landmarks[28];
	face_outline[1][3]=landmarks[25];
	face_outline[1][4]=landmarks[19];
	face_outline[1][5]=landmarks[22];
	face_outline[1][6]=landmarks[21];
	ppt[0]=face_outline[1];
	npt[0] = 7 ;
	fillPoly( mask,ppt,npt,1,Scalar( 0, 0, 0 ), 8);

	face_outline[5][0]=landmarks[34];
	face_outline[5][1]=landmarks[35];
	face_outline[5][2]=landmarks[36];
	face_outline[5][3]=landmarks[33];
	face_outline[5][4]=landmarks[32];
	face_outline[5][5]=landmarks[31];
	face_outline[5][6]=landmarks[30];
	face_outline[5][7]=landmarks[29];
	ppt[0]=face_outline[5];
	npt[0] = 8 ;
	fillPoly( mask,ppt,npt,1,Scalar( 0, 0, 0 ), 8);

	// right eye
	// expand the left eye
	int right_eye_expand = (int)sqrtf((landmarks[25].x - landmarks[55].x)*(landmarks[25].x - landmarks[55].x) + (landmarks[25].y - landmarks[55].y)*(landmarks[25].y - landmarks[55].y))/3;

	landmarks[67].x -= right_eye_expand * 2;
	landmarks[71].x += right_eye_expand * 2;

	landmarks[72].y -= right_eye_expand;
	landmarks[73].y -= right_eye_expand;
	landmarks[74].y -= right_eye_expand;

	landmarks[65].y += right_eye_expand;
	landmarks[68].y += right_eye_expand;
	landmarks[69].y += right_eye_expand;

	face_outline[2][0]=landmarks[67];
	face_outline[2][1]=landmarks[73];
	face_outline[2][2]=landmarks[72];
	face_outline[2][3]=landmarks[74];
	face_outline[2][4]=landmarks[71];
	face_outline[2][5]=landmarks[69];
	face_outline[2][6]=landmarks[65];
	face_outline[2][7]=landmarks[67];
	ppt[0]=face_outline[2];
	npt[0] = 8 ;
	fillPoly( mask,ppt,npt,1,Scalar( 0, 0, 0 ), 8);

	

	face_outline[6][0]=landmarks[75];
	face_outline[6][1]=landmarks[80];
	face_outline[6][2]=landmarks[81];
	face_outline[6][3]=landmarks[82];
	face_outline[6][4]=landmarks[79];
	face_outline[6][5]=landmarks[78];
	face_outline[6][6]=landmarks[77];
	face_outline[6][7]=landmarks[76];
	ppt[0]=face_outline[6];
	npt[0] = 8 ;
	fillPoly( mask,ppt,npt,1,Scalar( 0, 0, 0 ), 8);

	// nose
	face_outline[3][0]=landmarks[56];
	face_outline[3][1]=landmarks[55];
	face_outline[3][2]=landmarks[59];
	face_outline[3][3]=landmarks[60];
	face_outline[3][4]=landmarks[63];
	face_outline[3][5]=landmarks[61];
	face_outline[3][6]=landmarks[58];
	face_outline[3][7]=landmarks[57];
	face_outline[3][8]=landmarks[62];

	ppt[0]=face_outline[3];
	npt[0] = 9 ;
	fillPoly( mask,ppt,npt,1,Scalar( 0, 0, 0 ), 8);

	// mouth
	face_outline[4][0]=landmarks[37];
	face_outline[4][1]=landmarks[49];
	face_outline[4][2]=landmarks[48];
	face_outline[4][3]=landmarks[54];
	face_outline[4][4]=landmarks[51];
	face_outline[4][5]=landmarks[52];
	face_outline[4][6]=landmarks[46];
	face_outline[4][7]=landmarks[43];
	face_outline[4][8]=landmarks[44];
	face_outline[4][9]=landmarks[38];
	face_outline[4][10]=landmarks[41];
	ppt[0]=face_outline[4];
	npt[0] = 11 ;
	fillPoly( mask,ppt,npt,1,Scalar( 0, 0, 0 ), 8);

	

	cvtColor(mask, mask1, CV_GRAY2BGRA);
}